<?php

namespace App\Services;

use App\Exceptions\BusinessException;
use App\Models\Acc as AccModel;
use App\Models\User as UserModel;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Ramsey\Uuid\Uuid;

class Acc
{
    protected UserModel $userModel;
    protected AccModel $accModel;
    const TOKEN_CACHE_TTL = 3600 * 24;

    public function __construct()
    {
        $this->userModel = new UserModel();
        $this->accModel = new AccModel();
    }

    /**
     * @param string $username
     * @param string $password
     * @return mixed
     * @throws BusinessException
     */
    public function login(string $username, string $password)
    {
        $acc = $this->accModel->where('acc_lg_name', $username)->with('user')->first();

        if (is_null($acc)) {
            throw new BusinessException('user not found', ResponseCode::USER_NOT_FOUND);
        }

        if (!Hash::check($password, $acc->acc_lg_pwd)) {
            throw new BusinessException('incorrect password', ResponseCode::INCORRECT_PASSWORD);
        }

        // generate token
        $uuid = Uuid::uuid4();
        $token = $uuid->toString();

        // update acc login data
        $acc->acc_lg_dt = date('Y-m-d H:i:s');
        $acc->acc_token = $token;
        $acc->save();

        // save user to cache
        Cache::add('USER:' . $token, $acc, self::TOKEN_CACHE_TTL);

        return $acc;
    }

    /**
     * @param string $token
     * @return mixed
     */
    public function isLogin(string $token)
    {
        return $this->accModel->where('acc_token', $token)->exists();
    }

    /**
     * @param string $token
     * @return mixed
     */
    public function getUser(string $token)
    {
        if (Cache::has('USER:' . $token)) {
            $user = Cache::get('USER:' . $token);
        } else {
            $user = $this->accModel->where('acc_token', $token)->with('user')->first();
            Cache::add('USER:' . $token, $user, self::TOKEN_CACHE_TTL);
        }

        return $user;
    }
}
